/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.demister.at.model;

import java.util.Comparator;
import java.util.TreeSet;

/**
 *
 * @author rock
 */
public class GravityArrangeCommand extends BlockCommand {

    private TreeSet<Block> active;

    public GravityArrangeCommand(BlockFrame frame, BlockTypeSchema schema) {
        super(frame, schema);
        active = new TreeSet<Block>(new BlockLowerBoundComparator());

    }

    @Override
    public void excute() {
        while (!active.isEmpty()) {
            Block b = active.pollLast();
            int bound = bound(b.getBottomRightPoint().getY(), b.getX(), b.getBottomRightPoint().getX());
            if (bound != -1) {
                if (!frame.isAtTop(b)) {
                    for (int i = 0; i <= b.getBottomRightPoint().getX();) {
                        Block b1 = frame.get(i, b.getY() - 1);
                        if (b1 != null) {
                            active.add(b1);
                            i = b1.getBottomRightPoint().getX() + 1;
                        } else {
                            i++;
                        }
                    }
                }
                frame.move(b, b.getX(), bound);
            }
        }
    }

    private int bound(int y, int x1, int x2) {
        int i, j;
        for (i = y + 1; i < frame.getHeight(); i++) {
            for (j = x1; j <= x2; j++) {
                if (frame.get(j, i) != null) {
                    break;
                }
            }
            if (j <= x2) {
                break;
            }
        }
        return i - 1 == y ? -1 : i - 1;
    }

    public void addBlock(Block b) {
        active.add(b);
    }

    public static class BlockLowerBoundComparator implements Comparator<Block> {

        public int compare(Block o1, Block o2) {
            return o1.getBottomRightPoint().compareTo(o2.getBottomRightPoint());
        }
    }
}
